/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package DataBase;

import Search.SubWord;
import java.io.*;
import java.net.*;
import java.util.*;
import edu.mit.jwi.Dictionary;
import edu.mit.jwi.IDictionary;
import edu.mit.jwi.item.*;
import edu.mit.jwi.morph.*;
import java.util.ArrayList;


/**
 *
 * @author FY
 */
public class Word {

/* InterFace of Word:
 *
 * Word(String WordStr)                       //Constructor , accept the WordString as Parameter
 * String getWord()                           //return the WordString
 * int getFamility(POS c)                     //get famility of the word for different pos(POS.NOUN/POS.VERB/POS.ADJECTIVE/POS.ADV)
 * int getTaggedCnt(POS c)                    //get taggedcount of the word for different pos(POS.NOUN/POS.VERB/POS.ADJECTIVE/POS.ADV)
 *
 * bool exist()                               //Whether this word its-self exists in WordNet
 * bool hasNounSense()                        //Whether this word is a noun
 * bool hasVerbSense()                        //Whether this word is a verb
 * bool hasAdjSense()                         //Whether this word is a Adjective
 * bool hasAdvSense()                         //Whether this word is a Adverb
 * bool hasRootForm()                         //Whether this word has RootForms
 *
 * ArrayList<String>    getRootForm(POS c)    //getRootForm. c:POS.NOUN/POS.VERB/POS.ADJECTIVE/POS.ADV
 * ArrayList<NounSense> getNounSense()        //return a list of sense of Nouns via Arraylist
 * ArrayList<VerbSense> getVerbSense()        //return a list of sense of Verbs via Arraylist
 * ArrayList<AdjSense>  getNounSense()        //return a list of sense of Adjectives via Arraylist
 * ArrayList<AdvSense>  getAdvSense()         //return a list of sense of Noun via Arraylist
 */
    private String lemma;          			  //word string
    private ArrayList<NounSense> nounSense;   //Sense of different pos.
    private ArrayList<VerbSense> verbSense;
    private ArrayList<AdjSense> adjSense;
    private ArrayList<AdvSense> advSense;
    private IDictionary dict;



    public Word(String str){

        dict = null;
      	try
	{

                String wnhome = System.getenv("WNHOME");
		String path = wnhome + File.separator + "dict";
		URL url = new URL("file", null, path);

		// construct the dictionary object and open it
		dict = new Dictionary(url);
		dict.open();
	}catch (Exception e)
        {
		e.printStackTrace();
	}
        lemma = str;
    }


    public String getWord(){
        return lemma;
    }


    public boolean exist()
    {
        IIndexWord ixw = null;
        for (POS c: POS.values())
        {
            ixw = dict.getIndexWord(lemma, c);
            if (ixw != null)
            {
                break;
            }
        }
        if (ixw == null)
        {
            return false;
        }
        return true;
    }


    public ArrayList<NounSense> getNounSense(){        //return a list of sense of Noun via Arraylist
        IIndexWord ixw = dict.getIndexWord(lemma, POS.NOUN);
        int cnt = ixw.getWordIDs().size();
        nounSense = new ArrayList<NounSense>();
        for(int i = 0; i < cnt; i ++)
        {
            nounSense.add(new NounSense(lemma, dict, POS.NOUN, i));
        }
        /*
        System.out.println("test");
        for(String word:nounSense.get(2).words)
        {
            IIndexWord ixw1 = dict.getIndexWord(word, POS.NOUN);
            System.out.println(ixw1.getWordIDs());
        }
        System.out.println("end");
         *
         */

        return nounSense;
    }

    public ArrayList<VerbSense> getVerbSense(){        //return a list of sense of Verb via Arraylist
        IIndexWord ixw = dict.getIndexWord(lemma, POS.VERB);
        int cnt = ixw.getWordIDs().size();
        verbSense = new ArrayList<VerbSense>();
        for(int i = 0; i < cnt; i ++)
        {
             verbSense.add(new VerbSense(lemma, dict, POS.VERB, i));
        }
        return verbSense;
    }

    public ArrayList<AdjSense> getAdjSense(){        //return a list of sense of Adjective via Arraylist
        IIndexWord ixw = dict.getIndexWord(lemma, POS.ADJECTIVE);
        int cnt = ixw.getWordIDs().size();
        adjSense = new ArrayList<AdjSense>();
        for(int i = 0; i < cnt; i ++)
        {
            adjSense.add(new AdjSense(lemma, dict, POS.ADJECTIVE, i));
        }
        return adjSense;
    }

    public ArrayList<AdvSense> getAdvSense(){        //return a list of sense of Adverb via Arraylist
        IIndexWord ixw = dict.getIndexWord(lemma, POS.ADVERB);
        int cnt = ixw.getWordIDs().size();
        advSense = new ArrayList<AdvSense>();
        for(int i = 0; i < cnt; i ++)
        { 
            advSense.add(new AdvSense(lemma, dict, POS.ADVERB, i));
        }
        return advSense;
    }

/*
NOUN	"s"	""
NOUN	"ses"	"s"
NOUN	"xes"	"x"
NOUN	"zes"	"z"
NOUN	"ches"	"ch"
NOUN	"shes"	"sh"
NOUN	"men"	"man"
NOUN	"ies"	"y"
 *
 */
    public ArrayList<String> getRootForm(POS c)
    {
       ;

        WordnetStemmer ws = new WordnetStemmer(dict);
        ArrayList<String> rf = new ArrayList<String>();
        ArrayList<String> fy = new ArrayList<String>();

        for(String t: ws.findStems(lemma, c))
        {
            if (!t.equals(lemma))
                        rf.add(t);
        }
        for (String t:rf)
        {
            if (!lemma.startsWith(t))
            {
                fy.add(t);
                continue;
            }
            switch(c)
            {
                case NOUN:boolean a = lemma.equals(t+"s");
                          boolean b =lemma.endsWith("ses")|| lemma.endsWith("xes")||lemma.endsWith("ches")
                                  ||lemma.endsWith("shes");
                          b = lemma.equals(t+"es") && b;
                        boolean d =  lemma.endsWith("ies") && lemma.endsWith("y");
                        d = (lemma.endsWith("men")&& lemma.endsWith("man")) || d;
                        if (a||b||d)
                        {
                            fy.add(t);

                        }
                        break;
                case VERB: boolean a1 = lemma.equals(t + "s") || lemma.equals(t + "es") || lemma.equals(t + "ing") ||lemma.equals(t + "ed");
                            boolean a2 = lemma.endsWith("ies") && t.endsWith("y");
                            boolean a3 = lemma.endsWith("ed") && t.endsWith("e");
                            boolean a4 = lemma.endsWith("ing") && t.endsWith("e");
                            if (a1 || a2 || a3 || a4)
                            {
                                fy.add(t);
                    }   break;
                case ADJECTIVE:boolean b1 = lemma.equals(t + "er") || lemma.equals(t + "est");
                                boolean b2 = lemma.endsWith("er") && t.endsWith("e");
                                  boolean b3 = lemma.endsWith("est") && t.endsWith("e");
                                  if (b1 || b2 || b3)
                                  {
                                      fy.add(t);
                                  }
                                  break;
                default:fy.add(t);break;

            }
        }

/*
VERB	"s"	""
VERB	"ies"	"y"
VERB	"es"	"e"
VERB	"es"	""
VERB	"ed"	"e"
VERB	"ed"	""
VERB	"ing"	"e"
VERB	"ing"	""
ADJ	"er"	""
ADJ	"est"	""
ADJ	"er"	"e"
ADJ	"est"	"e"
   */
    

        return fy;
    }

    public boolean hasRootForm(){
         SimpleStemmer ss = new SimpleStemmer();

        List<String> lst = null;
        for (POS c: POS.values()){
                     if(ss.findStems(lemma, c).contains(""))
        {
            return false;
        }
            lst = getRootForm(c);
            if (!lst.isEmpty())
            {
                return true;
            }
        }
        return false;
    }

    public boolean hasNounSense(){
        IIndexWord ixw = dict.getIndexWord(lemma, POS.NOUN);
        if (ixw == null)
        {
               return false;
        }
        return true;
    }


    public boolean hasVerbSense(){
        IIndexWord ixw = dict.getIndexWord(lemma, POS.VERB);
        if (ixw == null)
        {
               return false;
        }
        return true;
    }

    public boolean hasAdjSense(){
        IIndexWord ixw = dict.getIndexWord(lemma, POS.ADJECTIVE);
        if (ixw == null)
        {
               return false;
        }
        return true;
    }

     public boolean hasAdvSense(){
        IIndexWord ixw = dict.getIndexWord(lemma, POS.ADVERB);
        if (ixw == null)
        {
               return false;
        }
        return true;
    }


    public int getFamility(POS c)
            /*return the famility of different POS
             * proper value of c:POS.NOUN,POS.VERB,POS.ADJECTIVE,POS.ADVERB
             */
    {
        switch(c)
        {
            case NOUN: return getNounSense().size(); 
            case VERB: return getVerbSense().size(); 
            case ADJECTIVE: return getAdjSense().size(); 
            case ADVERB:    return getAdvSense().size();
            default:return 0;
        }
    }

    public int getTaggedCnt(POS c)
            /*return the TaggedCnt of different POS
             * proper value of c:POS.NOUN,POS.VERB,POS.ADJECTIVE,POS.ADVERB
             */
    {
        IIndexWord ixw = dict.getIndexWord(lemma, c);
        return ixw.getTagSenseCount();
    }


}
